// onjava/HTMLColors.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Sample data for collection examples
package onjava;

import java.util.*;
import java.util.stream.Collectors;

public class HTMLColors {
    public static final Object[][] ARRAY = {
            {0xF0F8FF, "AliceBlue"},
            {0xFAEBD7, "AntiqueWhite"},
            {0x7FFFD4, "Aquamarine"},
            {0xF0FFFF, "Azure"},
            {0xF5F5DC, "Beige"},
            {0xFFE4C4, "Bisque"},
            {0x000000, "Black"},
            {0xFFEBCD, "BlanchedAlmond"},
            {0x0000FF, "Blue"},
            {0x8A2BE2, "BlueViolet"},
            {0xA52A2A, "Brown"},
            {0xDEB887, "BurlyWood"},
            {0x5F9EA0, "CadetBlue"},
            {0x7FFF00, "Chartreuse"},
            {0xD2691E, "Chocolate"},
            {0xFF7F50, "Coral"},
            {0x6495ED, "CornflowerBlue"},
            {0xFFF8DC, "Cornsilk"},
            {0xDC143C, "Crimson"},
            {0x00FFFF, "Cyan"},
            {0x00008B, "DarkBlue"},
            {0x008B8B, "DarkCyan"},
            {0xB8860B, "DarkGoldenRod"},
            {0xA9A9A9, "DarkGray"},
            {0x006400, "DarkGreen"},
            {0xBDB76B, "DarkKhaki"},
            {0x8B008B, "DarkMagenta"},
            {0x556B2F, "DarkOliveGreen"},
            {0xFF8C00, "DarkOrange"},
            {0x9932CC, "DarkOrchid"},
            {0x8B0000, "DarkRed"},
            {0xE9967A, "DarkSalmon"},
            {0x8FBC8F, "DarkSeaGreen"},
            {0x483D8B, "DarkSlateBlue"},
            {0x2F4F4F, "DarkSlateGray"},
            {0x00CED1, "DarkTurquoise"},
            {0x9400D3, "DarkViolet"},
            {0xFF1493, "DeepPink"},
            {0x00BFFF, "DeepSkyBlue"},
            {0x696969, "DimGray"},
            {0x1E90FF, "DodgerBlue"},
            {0xB22222, "FireBrick"},
            {0xFFFAF0, "FloralWhite"},
            {0x228B22, "ForestGreen"},
            {0xDCDCDC, "Gainsboro"},
            {0xF8F8FF, "GhostWhite"},
            {0xFFD700, "Gold"},
            {0xDAA520, "GoldenRod"},
            {0x808080, "Gray"},
            {0x008000, "Green"},
            {0xADFF2F, "GreenYellow"},
            {0xF0FFF0, "HoneyDew"},
            {0xFF69B4, "HotPink"},
            {0xCD5C5C, "IndianRed"},
            {0x4B0082, "Indigo"},
            {0xFFFFF0, "Ivory"},
            {0xF0E68C, "Khaki"},
            {0xE6E6FA, "Lavender"},
            {0xFFF0F5, "LavenderBlush"},
            {0x7CFC00, "LawnGreen"},
            {0xFFFACD, "LemonChiffon"},
            {0xADD8E6, "LightBlue"},
            {0xF08080, "LightCoral"},
            {0xE0FFFF, "LightCyan"},
            {0xFAFAD2, "LightGoldenRodYellow"},
            {0xD3D3D3, "LightGray"},
            {0x90EE90, "LightGreen"},
            {0xFFB6C1, "LightPink"},
            {0xFFA07A, "LightSalmon"},
            {0x20B2AA, "LightSeaGreen"},
            {0x87CEFA, "LightSkyBlue"},
            {0x778899, "LightSlateGray"},
            {0xB0C4DE, "LightSteelBlue"},
            {0xFFFFE0, "LightYellow"},
            {0x00FF00, "Lime"},
            {0x32CD32, "LimeGreen"},
            {0xFAF0E6, "Linen"},
            {0xFF00FF, "Magenta"},
            {0x800000, "Maroon"},
            {0x66CDAA, "MediumAquaMarine"},
            {0x0000CD, "MediumBlue"},
            {0xBA55D3, "MediumOrchid"},
            {0x9370DB, "MediumPurple"},
            {0x3CB371, "MediumSeaGreen"},
            {0x7B68EE, "MediumSlateBlue"},
            {0x00FA9A, "MediumSpringGreen"},
            {0x48D1CC, "MediumTurquoise"},
            {0xC71585, "MediumVioletRed"},
            {0x191970, "MidnightBlue"},
            {0xF5FFFA, "MintCream"},
            {0xFFE4E1, "MistyRose"},
            {0xFFE4B5, "Moccasin"},
            {0xFFDEAD, "NavajoWhite"},
            {0x000080, "Navy"},
            {0xFDF5E6, "OldLace"},
            {0x808000, "Olive"},
            {0x6B8E23, "OliveDrab"},
            {0xFFA500, "Orange"},
            {0xFF4500, "OrangeRed"},
            {0xDA70D6, "Orchid"},
            {0xEEE8AA, "PaleGoldenRod"},
            {0x98FB98, "PaleGreen"},
            {0xAFEEEE, "PaleTurquoise"},
            {0xDB7093, "PaleVioletRed"},
            {0xFFEFD5, "PapayaWhip"},
            {0xFFDAB9, "PeachPuff"},
            {0xCD853F, "Peru"},
            {0xFFC0CB, "Pink"},
            {0xDDA0DD, "Plum"},
            {0xB0E0E6, "PowderBlue"},
            {0x800080, "Purple"},
            {0xFF0000, "Red"},
            {0xBC8F8F, "RosyBrown"},
            {0x4169E1, "RoyalBlue"},
            {0x8B4513, "SaddleBrown"},
            {0xFA8072, "Salmon"},
            {0xF4A460, "SandyBrown"},
            {0x2E8B57, "SeaGreen"},
            {0xFFF5EE, "SeaShell"},
            {0xA0522D, "Sienna"},
            {0xC0C0C0, "Silver"},
            {0x87CEEB, "SkyBlue"},
            {0x6A5ACD, "SlateBlue"},
            {0x708090, "SlateGray"},
            {0xFFFAFA, "Snow"},
            {0x00FF7F, "SpringGreen"},
            {0x4682B4, "SteelBlue"},
            {0xD2B48C, "Tan"},
            {0x008080, "Teal"},
            {0xD8BFD8, "Thistle"},
            {0xFF6347, "Tomato"},
            {0x40E0D0, "Turquoise"},
            {0xEE82EE, "Violet"},
            {0xF5DEB3, "Wheat"},
            {0xFFFFFF, "White"},
            {0xF5F5F5, "WhiteSmoke"},
            {0xFFFF00, "Yellow"},
            {0x9ACD32, "YellowGreen"},
    };
    public static final Map<Integer, String> MAP =
            Arrays.stream(ARRAY)
                    .collect(Collectors.toMap(
                            element -> (Integer) element[0],
                            element -> (String) element[1],
                            (v1, v2) -> { // Merge function
                                throw new IllegalStateException();
                            },
                            LinkedHashMap::new
                    ));

    // Inversion only works if values are unique:
    public static <V, K> Map<V, K>
    invert(Map<K, V> map) {
        return map.entrySet().stream()
                .collect(Collectors.toMap(
                        Map.Entry::getValue,
                        Map.Entry::getKey,
                        (v1, v2) -> {
                            throw new IllegalStateException();
                        },
                        LinkedHashMap::new
                ));
    }

    public static final Map<String, Integer>
            INVMAP = invert(MAP);

    // Look up RGB value given a name:
    public static Integer rgb(String colorName) {
        return INVMAP.get(colorName);
    }

    public static final List<String> LIST =
            Arrays.stream(ARRAY)
                    .map(item -> (String) item[1])
                    .collect(Collectors.toList());
    public static final List<Integer> RGBLIST =
            Arrays.stream(ARRAY)
                    .map(item -> (Integer) item[0])
                    .collect(Collectors.toList());

    public static void show(Map.Entry<Integer, String> e) {
        System.out.format(
                "0x%06X: %s%n", e.getKey(), e.getValue());
    }

    public static void
    show(Map<Integer, String> m, int count) {
        m.entrySet().stream()
                .limit(count)
                .forEach(e -> show(e));
    }

    public static void show(Map<Integer, String> m) {
        show(m, m.size());
    }

    public static void show(Collection<String> lst, int count) {
        lst.stream()
                .limit(count)
                .forEach(System.out::println);
    }

    public static void show(Collection<String> lst) {
        show(lst, lst.size());
    }

    public static void showrgb(Collection<Integer> lst, int count) {
        lst.stream()
                .limit(count)
                .forEach(n -> System.out.format("0x%06X%n", n));
    }

    public static void showrgb(Collection<Integer> lst) {
        showrgb(lst, lst.size());
    }

    public static void showInv(Map<String, Integer> m, int count) {
        m.entrySet().stream()
                .limit(count)
                .forEach(e ->
                        System.out.format(
                                "%-20s  0x%06X%n", e.getKey(), e.getValue()));
    }

    public static void showInv(Map<String, Integer> m) {
        showInv(m, m.size());
    }

    public static void border() {
        System.out.println(
                "******************************");
    }
}
